#ifndef _TASK_H_
#define _TASK_H_

#include "list.h"

/* the definition of task attribute and data type */
typedef uint8_t                             task_type_t;
typedef uint8_t                             task_flag_t;

typedef uint8_t                             task_prio_t;
typedef uint8_t                             task_tick_t;

/*
 *
 */
enum {
	TASK_STATE_INIT = 0,
	TASK_STATE_READY,
	TASK_STATE_SUSPEND,
	TASK_STATE_SLEEP,
	TASK_STATE_CLOSED,
    TASK_STATE_DELETE,
    
	TASK_STATE_MAX
};

enum {
	TASK_TYPE_USER = 0,
	TASK_TYPE_IDLE,
	TASK_TYPE_KERNEL,

	TASK_TYPE_MAX
};

#define TASK_TICKS_MIN         1
#define TASK_TICKS_MAX         255

#define TASK_PRIORITY_MIN      0
#define TASK_PRIORITY_MAX      31

#define TASK_READY_GROUP_MAX   TASK_PRIORITY_MAX + 1

struct task
{
	task_type_t                             type;
	task_flag_t                             status;

    list_t                                  list;
    list_t                                  tlist;

    /* thread phy addr stack point */
    char                                    *sp;

    /* thread tick slice */
    task_tick_t                             init_ticks;
    task_tick_t                             cur_ticks;

    /* thread sleep ticks */
    uint16_t                                sleep_ticks;

    /* thread priority */
    task_prio_t                             init_prio;
    task_prio_t                             cur_prio;
    uint32_t                                prio_mask;

    /* thread function and user data */
    void                                    (*start_routine)(void *);
    void                                    *arg;

    /* thread stack info */
    char                                    *stk_addr;
    size_t                                  stk_size;
};
typedef struct task                         task_t;

void tasksched_init(void);
void tasksched_switch_thread(void);
void tasksched_start(void);

uint32_t tasksched_suspend(void);
void tasksched_recover(uint32_t state);

void tasksched_insert_task(task_t *);
void tasksched_set_task_ready(task_t *);
void tasksched_set_task_suspend(task_t *);
void tasksched_set_task_sleep(task_t *);
void tasksched_set_task_close(task_t *);
void tasksched_set_task_priority(task_t *, uint16_t);
void tasksched_delete_task(task_t *);

extern task_t* current_task;
#define __get_current_task() (current_task)

void __tasksched_disable (void);
void __tasksched_enable(void);

task_t* task_create(void (*)(void *), const char *, char *, size_t, void *,
			task_prio_t , task_tick_t , task_type_t);

#endif
